package com.jy.task.fileoper;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.EnumSet;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.hierynomus.msdtyp.AccessMask;
import com.hierynomus.msfscc.fileinformation.FileIdBothDirectoryInformation;
import com.hierynomus.mssmb2.SMB2CreateDisposition;
import com.hierynomus.mssmb2.SMB2ShareAccess;
import com.hierynomus.smbj.SMBClient;
import com.hierynomus.smbj.SmbConfig;
import com.hierynomus.smbj.auth.AuthenticationContext;
import com.hierynomus.smbj.connection.Connection;
import com.hierynomus.smbj.session.Session;
import com.hierynomus.smbj.share.DiskShare;
import com.hierynomus.smbj.share.File;
import com.jy.common.utils.base.Tools;
import com.jy.common.utils.base.UuidUtil;
import com.jy.entity.filemanager.TSFile;

/**
 * SMB2连接示例 例: 我们当前要连接 IP为:123.123.123.123 目录为: SRC/SMB2/ 下的文件
 * 
 * @author yuanqi
 * 
 */
public class SMB2Connect {

	private String ip = "";
	private String userName = "";
	private String psw = "";
	private String fileNameStr = "";
	private static DiskShare share;
	private static DiskShare share1;
	private static SMBClient client;

	private List<TSFile> fileStr;
	private String fileName;// 文件名
	private Date startDate;
	private Integer isSubFile;// 是否包含子文件夾
	private Date newDate;// 最新文件时间

	public SMB2Connect(String ip, String userName, String psw,
			String fileNameStr, String fileName, Date startDate,
			Integer isSubFile) {
		this.ip = ip;
		this.userName = userName;
		this.psw = psw;
		this.fileNameStr = fileNameStr;
		fileStr = new ArrayList<TSFile>();
		this.fileName = fileName;
		this.startDate = startDate;
		this.isSubFile = isSubFile;
	}

	/**
	 * 判斷smb2 是否能连接
	 * 
	 * @return
	 */
	public boolean smb2Connect() {
		boolean result = false;
		// 设置超时时间(可选)
		SmbConfig config = SmbConfig.builder()
				.withTimeout(12000, TimeUnit.SECONDS)
				.withTimeout(12000, TimeUnit.SECONDS) // 超时设置读，写和Transact超时（默认为60秒）
				.withSoTimeout(18000, TimeUnit.SECONDS) // Socket超时（默认为0秒）
				.build();

		// 如果不设置超时时间 SMBClient client = new SMBClient();
		client = new SMBClient(config);
		try {
			Connection connection = client.connect(ip);
			AuthenticationContext ac = new AuthenticationContext(userName,
					psw.toCharArray(), ip);
			Session session = connection.authenticate(ac);
			share = (DiskShare) session.connectShare(fileNameStr);
			if (share.isConnected()) {
				result = true;
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}

	public boolean smbToSmbInfo(String folder, String dstRoot, String ipNew,
			String userNamNew, String pswNew, String fileName) {
		boolean result = true;
		Connection connection1;
		try {
			connection1 = client.connect(ipNew);
			AuthenticationContext ac = new AuthenticationContext(userNamNew,
					pswNew.toCharArray(), ipNew);
			Session session = connection1.authenticate(ac);
			share1 = (DiskShare) session.connectShare(fileName);
			if (share1.isConnected()) {
				result = true;
				result = smbToSmbDirectory(folder, dstRoot);
			} else {
				result = false;
			}
		} catch (IOException e) {
			result = false;
			e.printStackTrace();
		}
		return result;

	}

	public boolean smbToSmbDirectory(String folder, String dstRoot) {
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
				"yyyy-MM-dd HH:mm:ss");
		boolean result = true;
		try {
			for (FileIdBothDirectoryInformation f : share.list(folder)) {
				if (f.getFileName().equals(".") || f.getFileName().equals("..")) {
					continue;
				}
				String filePath = folder + f.getFileName();
				String dstPath = dstRoot + f.getFileName();
				if (share.fileExists(filePath)) {
					String dateTime = simpleDateFormat.format(f
							.getLastWriteTime().toDate());
					setNewDate(simpleDateFormat.parse(dateTime));
					// 文件時間是否在规定范围
					if (compareToDate(simpleDateFormat.parse(dateTime),
							simpleDateFormat.parse(simpleDateFormat
									.format(this.startDate)))) {
						if (!Tools.isEmpty(this.fileName)) {
							if (patternStr(f.getFileName())) {
								smbTosmb(filePath, dstPath, f.getFileName());
							}
						} else {
							smbTosmb(filePath, dstPath, f.getFileName());
						}

					}
				} else if (share.folderExists(filePath)) {
					if (this.isSubFile == 1) {
						if (!share1.folderExists(dstPath)) {
							share1.mkdir(dstPath);
						}
						smbToSmbDirectory(folder + f.getFileName() + "/",
								dstRoot + f.getFileName() + "/");
					}
				}
			}
		} catch (Exception e) {
			result = false;
			e.printStackTrace();

		} finally {
			// share.close();
			// share1.close();
			if (client != null) {
				client.close();
			}
		}
		return result;
	}

	public boolean smbTosmb(String filePath, String dstPath, String fielName) {
		boolean result = true;
		InputStream in = null;
		OutputStream out = null;
		try {
			if (share.fileExists(filePath)) {
				File smbFileRead = share.openFile(filePath,
						EnumSet.of(AccessMask.GENERIC_READ), null,
						SMB2ShareAccess.ALL, SMB2CreateDisposition.FILE_OPEN,
						null);
				File smbFileRead1 = share1.openFile(dstPath,
						EnumSet.of(AccessMask.GENERIC_WRITE), null,
						SMB2ShareAccess.ALL,
						SMB2CreateDisposition.FILE_OVERWRITE_IF, null);
				in = smbFileRead.getInputStream();
				out = smbFileRead1.getOutputStream();
				byte[] buffer = new byte[4096];
				int len = 0;
				while ((len = in.read(buffer, 0, buffer.length)) != -1) {
					out.write(buffer, 0, len);
				}
				TSFile objFile = new TSFile();
				objFile.setId(UuidUtil.get32UUID());
				objFile.setFileName(fielName);
				fileStr.add(objFile);
			}
		} catch (Exception e) {
			result = false;
			e.printStackTrace();

		} finally {
			try {
				out.flush();
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return result;
	}

	private boolean patternStr(String str) {
		String newString[] = (this.fileName).split(",");
		boolean rs = false;
		for (String reg : newString) {
			String regEx = reg.replace(".", "/").replace("?", ".?")
					.replace("*", ".*");
			Pattern pattern = Pattern.compile(regEx);
			Pattern pat = Pattern.compile(regEx, Pattern.CASE_INSENSITIVE);
			Matcher matcher = pattern.matcher(str);
			rs = matcher.find();
			if (rs)
				break;
		}
		// 查找字符串中是否有匹配正则表达式的字符/字符串
		return rs;
	}

	private void setNewDate(Date dateStr) {
		if (newDate != null) {
			if (compareToDate(dateStr, newDate)) {
				newDate = dateStr;
			}
		} else {
			newDate = dateStr;
		}
	}

	public Date getNewDate() {
		return newDate;
	}

	private boolean compareToDate(Date date1, Date date2) {
		if (date1.getTime() > date2.getTime()) {
			return true;
		}
		return false;
	}

	public boolean smbTosmbMother(String folder, String dstRoot, String ipNew,
			String pswNew, String userNamNew, String fileName) {
		smb2Connect();
		boolean result = true;
		result = smbToSmbInfo(folder, dstRoot, ipNew, pswNew, userNamNew,
				fileName);
		if (!result)
			newDate = null;
		return result;
	}

	public List<TSFile> getresultFIle() {
		return fileStr;
	}

}
